package org.zjt.scala.book

import java.nio.ByteBuffer
import java.nio.charset.Charset

import scala.collection.mutable.ArrayBuffer
import scala.io.StdIn
import scala.reflect.io.File
import scala.util.control.Breaks
/**
  *
  * Description:
  *
  *   条件表达式[无三目]： if 、else
  *   块表达式 ：         {block ; return}
  *   输入输出：{@link scala.io.StdIn}
  *   循环    ：         while 、for-each、do while、break
  *   高级for：          for嵌套、for推导式、守卫模式、yield
  *   序列与长度可变参数：    :_* 将数组转为长度可变参数（seq）
  *   函数：             一行、多行、结构【无返回值、无等号】、无括号【无参数】
  *
  *   懒值：             lazy
  *   异常:              都是非检查异常
  *
  *
  *
  * @author juntao.zhang
  *         Date: 2018-06-26 上午11:26
  * @see
  */
class Chapter2 {

  /**
    * 条件判断。实现三目运算符号。
    * @param x
    * @param y
    * @return
    */
  def condition(x:Int, y:Int): Int ={
    if(x > y) x else y
  }


  def condition1(x:Int, y:Int): Int ={
    if(x > y) { println("x 比较大"); x } else { println("y 比较大"); y }
  }


  /**
    * 无返回值，可以为过程。就不用写返回值和=号
    *
    * @param args
    */
  def loop(args : Int *){
    for(arg <- args){
      println(arg)
    }
  }

  def loop1(args : Int *){
    var i = 0
    while(i < args.length){
      println(args.apply(i))
      i+=1
    }
  }


  def loop2(args : Int *){
    var i = 0
    do {
      println(args.apply(i))
      i += 1
    } while(i < args.length)
  }


  /**
    * break
    * @param args
    */
  def loopBreak(args : Int *){
    val loop = new Breaks()

    var i = 0
    loop.breakable{
      do {
        println(args.apply(i))
        i += 1
        // 此处不能
        if(i % 2 == 0) { loop.break(); println("break") }
      } while(i < args.length)
    }
  }

  /**
    * for 嵌套的循环
    */
  def innerLoop(): Unit ={
    for(i <- 0 to 5; j <- 0 to 5) println(i, j)
  }

  /**
    * for 推导式    [j = i : 将循环中的 i 赋值给 j ]
    */
  def innerLoop2(): Unit ={
    for(i <- 0 to 5 ; j = i;  x <- j to 8) println(i,j,x)
  }

  /**
    * 守卫模式    x <- j to 8 if j %2 == 0
    *
    *   循环语句中增加判断条件
    */
  def conditionalLoop(): Unit ={
    for(i <- 0 to 5 ; j = i;  x <- j to 8 if j %2 == 0) println(i,j,x)

  }


  /**
    * yield 返回元素
    * @return
    */
  def yieldLoop(): Array[Int] ={
    val seq = for(i <- 0 to 5 ; j = i;  x <- j to 8 if j %2 == 0) yield i * 10 + j
    seq.toArray
  }

  /**
    * 无参数【无括号】、 无等号（结构） 【无返回值】
    */
  def show{ println("-------show-------") }


  /**
    * 读取文件
    * @return
    */
  def readFile(filepath:String): Option[String] ={
    val file = new java.io.File(filepath)
    assert(file.exists())
    val fileChannel = new File(file).inputStream().getChannel
    try {
      val buffer = ByteBuffer.allocate(48)
      var arrayBuffer = ArrayBuffer[String]()
      val charset = Charset.defaultCharset()
      while (fileChannel.read(buffer) != -1) {
        buffer.rewind
        arrayBuffer += charset.decode(buffer).toString()
        buffer.flip()
      }
      Option(arrayBuffer.mkString)
    }catch {
      case e : Exception => e.printStackTrace() ; Option.empty
    }finally {
      fileChannel.close()
    }
  }

}

/**
  * 单例、静态的作用域
  */

object Chapter2 extends App {


  lazy val lazyNum = { println("----1---"); 200 }

  val lazyNum2 = { println("---2----"); 200 }

  // 块表达式 ： 执行整个块，并将最后一个执行结果赋值给param1
  val param1 = {var x = 0 ; val y = 2; x += 1; x + y}
  println(param1)


  val chapter2 = new Chapter2()
  println(chapter2.condition(2,3))
  println(chapter2.condition1(2,3))


  val account = StdIn.readLine("请输入账号")
  val password = StdIn.readLine("请输入密码")
  println(account,password)


  // 1 to 5 产生数组， :_* 将数组转为序列seq。seq才是可变参数的值
  chapter2.loop(1 to 5 :_*)
  chapter2.loop1(1 to 5 :_*)
  chapter2.loop2(1 to 5 :_*)
  chapter2.loopBreak(1 to 5 :_*)


  chapter2.innerLoop()
  chapter2.conditionalLoop()
  chapter2.yieldLoop().foreach(println)

  chapter2.show

  print(lazyNum)

  println(chapter2.readFile("/Users/juntao.zhang/dev/workspace/myproject/scala-akka-demo/src/main/scala/org/zjt/scala/book/Chapter2.scala"))
}